#include "character.h"
#include "point2d.h"
#include <string.h> // yaaay strtok()
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;

Character::Character(): owner(0), moveSpeed(0), carryingCap(0),location(point2d(0,0)),techLevel(0),lumber(0),ore(0),food(0){} 
//default Character constructor for Characters, creates an object with all member variables initialized to 0.
Character::Character(const point2d& loc, const unsigned int& _owner): location(loc), owner(_owner), moveSpeed(0), carryingCap(0),techLevel(0),lumber(0),ore(0),food(0){} 
//Character constructor that accepts a point2d (for an object's location) and an unsigned int (for the owner)
Character::~Character(){} 
//Character destructor, should probably also have a version that can accept a vector as a parameter in order to properly delete a Character from it.

void Character::setLocation(const point2d& loc){
	location.x=loc.x;
	location.y=loc.y;
	}


point2d Character::getLocation(){ return location; }

short Character::getLocation(const char& coord){
	if (coord=='x' || coord=='X'){ return getLocation().x; } 
     else { if (coord=='y' || coord=='Y') { return getLocation().y; }
          else { return 0; } //if an invalid character is passed, nothing is returned.
}
}

//huge block of getters and setters

unsigned short Character::getFood() { return food; }
unsigned short Character::getOre() { return ore; }
unsigned short Character::getLumber() { return lumber; }
unsigned short Character::movement(){ return moveSpeed; }
unsigned int Character::getOwner(){ return owner; }

void Character::setFood(const unsigned short& val) { food = val; }
void Character::setOre(const unsigned short& val) { ore = val; }
void Character::setLumber(const unsigned short& val) { lumber = val; }
void Character::setOwner(const unsigned int& _owner){ owner = _owner; }
void Character::setLocation(const short& x, const short& y){ location=point2d(x,y); }
void Character::setMoveSpeed(const unsigned  short& newSpeed){ moveSpeed = newSpeed; }
void Character::setCarryingCap(const unsigned short& newCap){ carryingCap=newCap; }
void Character::setTechLevel(const unsigned short& newLevel){ techLevel=newLevel; }

/*
make sure to close the in/out streams and reopen them as the proper type of stream (depending on which operator you're using) before you use the operators. failing to be responsible with the files will cause segfaults (i know because i did it about 50000 times while testing these)

"but how can i do that, when i need to create objects and read them at the same time blah blah" ... use a 
vector <Character> bunchOfChars;
or a stack or a linked list or something.. but a vector seems to work... as a buffer to read the file into, and only read/write using the operators at the beginning/end of a game session. The << operator can be useful for printing out character data for debugging, but you'd better understand the format it spits out. 

--George
*/

ostream& operator<<(ostream& out, Character& character)
{
    out << "o" << character.getOwner() 
    << ":" << "L" << character.getLocation().x << " " << character.getLocation().y<< ","  
    << "oo" << character.getOre() << ","
    << "ll" << character.getLumber() << ","
    << "ff" << character.getFood() << ";"
    << endl;
return out;
}

ostream& operator<<(ostream& out, vector <Character>& characters)
{
  vector<Character>::iterator i;
	i = characters.begin();
	while (i!=characters.end()){ out << *i; i++; }
return out;
}

istream& operator>>(istream& in, Character& character)
{
	char* temp;
	char infoStr[100];
	
	in.getline(infoStr,100);
	if (in.eof()) return in;

	temp= strtok(infoStr,"o:Llf,;");					//this is the first token (owner)
	character.setOwner(atoi(temp));
	
  temp= strtok(NULL,"o:Llf,; ");					//this is the second token (location)
	short x = static_cast<unsigned short>(atoi(temp));
	temp = strtok(NULL,"o:Llf,; ");
	short y = static_cast<unsigned short>(atoi(temp));
	character.setLocation(point2d(x,y));
	
	temp= strtok(NULL,"o:Llf,;");					//this is the third token (ore)
	character.setOre(atoi(temp));
	
  temp= strtok(NULL,"o:Llf,;");					//this is the fourth token (Lumber)
	character.setLumber(atoi(temp));
	
  temp= strtok(NULL,"o:Llf,;");					//this is the fifth token (food)
	character.setFood(atoi(temp));
 
	return in; //don't hog the stream

}
istream& operator>>(istream& in, vector <Character>& characters)
{
	char* temp;
	char infoStr[100];
	Character character;
	
		in.getline(infoStr,100);
		if (in.eof()) return in;
		
    temp= strtok(infoStr,"o:Llf,;");					//this is the first token (owner)
		character.setOwner(atoi(temp));
		
    temp= strtok(NULL,"o:Llf,; ");					//this is the second token (location)
		short x = static_cast<unsigned short>(atoi(temp));
		temp = strtok(NULL,"o:Llf,; ");
		short y = static_cast<unsigned short>(atoi(temp));
		character.setLocation(point2d(x,y));
		
    temp= strtok(NULL,"o:Llf,;");					//this is the third token (ore)
		character.setOre(atoi(temp));
		
    temp= strtok(NULL,"o:Llf,;");					//this is the fourth token (Lumber)
		character.setLumber(atoi(temp));
		
    temp= strtok(NULL,"o:Llf,;");					//this is the fifth token (food)
		character.setFood(atoi(temp));
 
	/*
	 *This needs to be cleaned up.
	 *Strtok() is the function of satan.
	 * */
		characters.push_back(character);
	
	return in;
}
